// 引入文件系统
const fs = require('fs');
// path
const path = require('path');
// 引入VM--执行字符串
const vm = require('vm');

/*************测试代码***************** */
// let flag = fs.existsSync('./generator.js');
// if (flag) {
//     // 同步读取文件，异步的不好操作
//     const content = fs.readFileSync('./generator.js', 'utf8');
//     console.log('content',content);
// }else{
//     throw new Error('文件不存在');
// }
// // 拼接并解析路径,这个方法可以解析./和../之类的相对路径
// let resolvePath = path.resolve(__dirname,'./generator.js');
// // 获取文件的扩展名====>.js
// let extName = path.extname('./generator.min.js');
// // 获取文件的主要的名字，去掉文件后缀 ====>generator.min
// let baseName = path.basename('./generator.min.js','.js');
/*************测试代码***************** */



const exp = require('./export');
console.log(exp);


/***************正文****************/

function Module (id) {
    this.id = id;
    this.exports = {};
}

/**
 * 根据不同的扩展名，处理文件的方式不同
 */
Module._extensions = {
    '.js' (module) {
        // 读取文件
        let content = fs.readFileSync(module.id, 'utf8');
        // 包装函数
        content = Module._moduleWrapper(content);
        // console.log(content);
        // 执行函数
        const fn = vm.runInThisContext(content);
        let exports = module.exports;
        let dirname = path.dirname(module.id);
        // 函数当中的this就是exports
        fn.call(exports, exports, req, module, module.id, dirname);
        // 返回module.exports
        // return module.exports;
    },
    '.json' (module) {
        let content = fs.readFileSync(module.id, 'utf8');
        module.exports = JSON.parse(content);
    }
}
/**
 * 包装执行代码段
 */
Module._moduleWrapper = function (content) {
    return '(function (exports, require, module, __filename, __dirname) { \r\n' + content + '\r\n })'
}
/**
 * 根据文件名，获取绝对路径
 * @param {引用文件名} fileName 
 */
Module._resolveFileName = function (fileName) {
    const absPath = path.resolve(__dirname, fileName);
    // 判断文件是不是存在，存在则返回文件路径，不存在则尝试添加后缀查找。
    if (fs.existsSync(absPath)) {
        return absPath;
    } else {
        // 尝试添加扩展名
        const keys = Object.keys(Module._extensions);
        keys.forEach(suffix => {
            let tempPath = absPath + suffix;
            if (fs.existsSync(tempPath)) {
                return tempPath;
            }
        });
        throw new Error('module not exists');
    }
}
/**
 * 加载文件的方法
 */
Module.prototype.load = function () {
    // 拿到文件扩展名、然后交给不同的函数处理就好
    let extname = path.extname(this.id);
    // 交给函数处理
    Module._extensions[extname](this);
}
/**
 * 模块的缓存
 */
Module._cache = {

}

function req (fileName) {
    // 获取绝对路径
    fileName = Module._resolveFileName(fileName);
    console.log(fileName);
    // 缓存中获取
    let cacheModule = Module._cache[fileName];
    if (!!cacheModule) {
        return cacheModule.exports;
    }
    // 创建module对象
    let module = new Module(fileName);
    // 读取文件，并处理
    module.load();
    // 缓存对象
    Module._cache[fileName] = module;
    // 返回对象
    return module.exports;
}

const r = req('./export.js');
console.log('返回值：', r)